package com.qinglei.recoup.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qinglei.recoup.common.exception.RecoupException;
import com.qinglei.recoup.common.service.CacheService;
import com.qinglei.recoup.common.tenant.TenantContextHolder;
import com.qinglei.recoup.common.utils.AesEncryptUtil;
import com.qinglei.recoup.common.utils.MD5Util;
import com.qinglei.recoup.common.utils.SortUtil;
import com.qinglei.recoup.system.dao.UserMapper;
import com.qinglei.recoup.system.dao.UserRoleMapper;
import com.qinglei.recoup.system.domain.DeptUsers;
import com.qinglei.recoup.system.domain.Tenant;
import com.qinglei.recoup.system.domain.User;
import com.qinglei.recoup.system.domain.UserRole;
import com.qinglei.recoup.system.manager.UserManager;
import com.qinglei.recoup.system.pojo.NurseWorkVO;
import com.qinglei.recoup.system.pojo.PageParam;
import com.qinglei.recoup.system.service.LoginService;
import com.qinglei.recoup.system.service.TenantService;
import com.qinglei.recoup.system.service.UserRoleService;
import com.qinglei.recoup.system.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Slf4j
@Service("userService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private UserManager userManager;
    @Autowired
    private TenantService tenantService;
    @Autowired
    private LoginService loginService;


    @Override
    public User findByMobile(String mobile) {
        return baseMapper.findDetailByMobile(mobile);
    }

    /**
     * 通过用户ID查找用户
     *
     * @param id id
     * @return user
     */
    @Override
    public User findById(Long id) {
        return baseMapper.findDetailById(id);
    }

    @Override
    public IPage<User> findUserDetail(User user, PageParam pageParam) {
        try {
            Page<User> page = new Page<>();
            SortUtil.handlePageSort(pageParam, page);
//            page.getOrders().add(OrderItem.asc("id"));
            return this.baseMapper.findUserDetail(page, user);
        } catch (Exception e) {
            log.error("查询用户异常", e);
            return null;
        }
    }

    @Override
    @Transactional
    public void updateLoginTime(Long userId) throws Exception {
        User user = new User();
        user.setId(userId);
        user.setLastLoginTime(new Date());
        this.updateById(user);

        // 重新将用户信息加载到 redis中
        cacheService.saveUser(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createUser(User user) throws Exception {
        Integer tenantId = TenantContextHolder.getTenantId();
        TenantContextHolder.clear();
        User userExist = this.baseMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getMobile, user.getMobile()));
        TenantContextHolder.setTenantId(tenantId);
        if (userExist != null) {
            throw new RecoupException("账号已存在");
        }

        // 创建用户
        user.setCreateTime(new Date());
        user.setAvatar(User.DEFAULT_AVATAR);
        String password = StringUtils.isNotEmpty(user.getPassword()) ? user.getPassword() : User.DEFAULT_PASSWORD;
        user.setPassword(MD5Util.encrypt(password));
        save(user);

        // 保存用户角色
        String[] roles = user.getRoleId().split(StringPool.COMMA);
        saveUserRoles(user, roles);
        //查询用户角色

        // 创建用户默认的个性化配置
//        userConfigService.initDefaultUserConfig(String.valueOf(user.getId()));

        // 将用户相关信息保存到 Redis中
        User detailById = baseMapper.findDetailById(user.getId());
        userManager.loadUserRedisCache(detailById);

        //更新用户所在部门缓存
//        cacheService.saveUserSubordinates(user.getDeptId(),findSubordinates(user.getDeptId()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(User user) throws Exception {
        // 更新用户
        if (StringUtils.isNotEmpty(user.getPassword())) {
            user.setPassword(MD5Util.encrypt(user.getPassword()));
        }
        user.setModifyTime(new Date());
        updateById(user);

        if (user.getRoleId() != null) {
            userRoleService.remove(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, user.getId()));
            if (StringUtils.isNotEmpty(user.getRoleId())) {
                String[] roles = user.getRoleId().split(StringPool.COMMA);
                saveUserRoles(user, roles);
            }
        }

        // 重新将用户信息，用户角色信息，用户权限信息 加载到 redis中
        cacheService.saveUser(user.getId());
        cacheService.saveRoles(user.getId());
        cacheService.savePermissions(user.getId());
        //更新用户所在部门缓存
//        cacheService.saveUserSubordinates(user.getDeptId(),findSubordinates(user.getDeptId()));
    }

    @Override
    @Transactional
    public void deleteUsers(String[] userIds) throws Exception {
        for (String userId : userIds) {
            User user = baseMapper.selectById(Long.valueOf(userId));
            if (user == null) {
                continue;
            }
            if (user.getTenantId() == 0) {
                throw new RecoupException("系统默认用户不可删除");
            }
            Tenant tenant = tenantService.getById(user.getTenantId());
            if (tenant != null && tenant.getAdminUserId().equals(user.getId())) {
                throw new RecoupException("系统默认用户不可删除");
            }
            // 删除用户
            this.baseMapper.deleteById(user.getId());
            // 先删除相应的缓存
            this.userManager.deleteUserRedisCache(userId);
            // 登出
            loginService.logout(user.getId());
        }

        // 删除用户角色
//        this.userRoleService.deleteUserRolesByUserId(userIds);
        // 删除用户个性化配置
//        this.userConfigService.deleteByUserId(userIds);
    }

    @Override
    @Transactional
    public void updateProfile(User user) throws Exception {
        updateById(user);
        // 重新缓存用户信息
        cacheService.saveUser(user.getId());
        //更新用户所在部门缓存
//        cacheService.saveUserSubordinates(user.getDeptId(),findSubordinates(user.getDeptId()));
    }

    @Override
    @Transactional
    public void updateAvatar(Long userId, String avatar) throws Exception {
        User user = new User();
        user.setId(userId);
        user.setAvatar(avatar);
        this.baseMapper.updateById(user);

        // 重新缓存用户信息
        cacheService.saveUser(userId);
    }

    @Override
    @Transactional
    public void updatePassword(Long userId, String password) throws Exception {
        User user = new User();
        user.setId(userId);
        user.setPassword(MD5Util.encrypt(password));
        this.baseMapper.updateById(user);
        // 重新缓存用户信息
        cacheService.saveUser(userId);
    }

    @Override
    @Transactional
    public void regist(String username, String password) throws Exception {
        User user = new User();
        user.setPassword(MD5Util.encrypt(AesEncryptUtil.decrypt(password)));
//        user.setUsername(username);
        user.setCreateTime(new Date());
        user.setStatus(User.STATUS_LOCK);
        user.setSsex(User.SEX_UNKNOW);
        user.setAvatar(User.DEFAULT_AVATAR);
        user.setDescription("注册用户");
        this.save(user);

        UserRole ur = new UserRole();
        ur.setUserId(user.getId());
        ur.setRoleId(2L); // 注册用户角色 ID
        userRoleService.save(ur);

        // 将用户相关信息保存到 Redis中
        userManager.loadUserRedisCache(user);
    }

    @Override
    @Transactional
    public void resetPassword(String[] userIds) throws Exception {
        for (String userIdStr : userIds) {
            Long userId = Long.valueOf(userIdStr);

            User user = new User();
            user.setId(userId);
            user.setPassword(MD5Util.encrypt(User.DEFAULT_PASSWORD));

            this.baseMapper.updateById(user);
            // 重新将用户信息加载到 redis中
            cacheService.saveUser(userId);
        }
    }

    private void saveUserRoles(User user, String[] roles) {
        for (String roleId : roles) {
            UserRole ur = new UserRole();
            ur.setUserId(user.getId());
            ur.setRoleId(Long.valueOf(roleId));
            userRoleService.save(ur);
        }
    }

    @Override
    public String findSubordinates(Long deptId) {
        return baseMapper.findSubordinates(deptId);
    }

    @Override
    public List<DeptUsers> findSubordinatesMap() {
        return baseMapper.findSubordinatesMap();
    }

    /**
     * 分页查询护工
     *
     * @param pageParam
     * @return
     */
    @Override
    public IPage<NurseWorkVO> pageNurse(PageParam pageParam, Integer tenantId) {
        Page<NurseWorkVO> page = new Page<>(pageParam.getPageNum(), pageParam.getPageSize());
        return baseMapper.pageNurse(page, tenantId);
    }

    @Override
    public User findByWxOpenId(String openId) {
        QueryWrapper queryWrapperUser = new QueryWrapper();
        queryWrapperUser.eq("weixin_openid",openId);
        queryWrapperUser.eq("is_deleted",0);
        return baseMapper.selectOne(queryWrapperUser);
    }



}
